using System;
using System.Runtime.InteropServices;
using System.Web.UI;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Serialization;
using System.Xml;
using Microsoft.SharePoint;
using Microsoft.SharePoint.WebControls;
using Microsoft.SharePoint.WebPartPages;
using WebPart=Microsoft.SharePoint.WebPartPages.WebPart;
using Microsoft.SharePoint.WebPartPages.Communication;
using System.Security;
using Microsoft.SharePoint.Utilities;
using System.Data;
using System.Xml.XPath;
using System.ComponentModel;
using System.Web.UI.WebControls;
using System.IO;

namespace PS.WebParts.Export
{

    //<SafeControl Assembly="PS.WebParts.ExcelReporting, Version=1.0.0.0, Culture=neutral, PublicKeyToken=eaff8e61ee275914" Namespace="PS.WebParts.ExcelReporting" TypeName="*" Safe="True" />
    [Guid("6174438f-6ba6-4757-9bc3-7a4b4971136f")]
    public class ExcelPart : Microsoft.SharePoint.WebPartPages.WebPart, IListConsumer
    {
        private const string defaulttp = "http://";

        private string templatePath = defaulttp;

        [  
        Category("Portal Solutions"),
                WebPartStorage(Storage.Personal), 
                DefaultValue(defaulttp),
        
                FriendlyName("Template Path"), 
                Description("The location of a template in Xml Spreadsheet 2003 format."),

                //NEW
                Personalizable(),
                WebBrowsable(true)
        ]
        
     
        public string TemplatePath
        {
            get
            {
                return templatePath;
            }

            set
            {
                templatePath = value;
            }
        }
      
      
        #region ImplementConsumer


        private bool _connected = false;
        private string _connectedWebPartTitle = string.Empty;
        private string _registrationErrorMsg = "An error has occurred trying to register your connection interfaces.";
        private bool _registrationErrorOccurred = false;
        private string _notConnectedMsg = "NOT CONNECTED. To use this Web Part connect it to a List Provider Web Part.";

        // Declare variables for Web Part user interface.
        private string _connectedWebPartLabel = "Connected to Web Part";
  


        // Step #3: Override EnsureInterfaces method and call 
        // RegisterInterface method.
        // EnsureInterfaces() is called by the Web Part infrastructure 
        // during the ASP.NET PreRender event 
        // and allows the part to register all of its connection 
        // interfaces.
        
        public override void EnsureInterfaces()
        {
            // If your Web Part is installed in the bin directory and 
            // the Code Access Security (CAS) setting doesn't 
            // allow Web Part Connections, an exception will be thrown. 
            // To allow your Web Part to behave 
            // well and continue working, a try/catch block should be 
            // used when attempting to register interfaces.
            // Web Part Connections will only work if the level 
            // attribute of the <trust> tag in the 
            // web.config file is set to WSS_Minimal, WSS_Medium, or 
            // Full. By default a new SharePoint site
            // is installed with the trust level set to WSS_Minimal.
            try
            {
                // Register the IListConsumer interface
                // <param name="interfaceName">Friendly name of the 
                // interface that is being implemented.</param>
                // <param name="interfaceType">Specifies which 
                // interface is being implemented.</param>
                // <param name="maxConnections">Defines how many times 
                // this interface can be connected.</param>
                // <param name="runAtOptions">Determines where the 
                // interface can run.</param>
                // <param name="interfaceObject">Reference to the 
                // object that is implementing this interface.</param>
                // <param name="interfaceClientReference">Name used to 
                // reference the interface on the client. 
                // This is a server side example so the value is set to 
                // empty string.</param>
                // <param name="menuLabel">Label for the interface 
                // that appears in the UI</param>
                // <param name="description">Description of the 
                // interface that appears in the UI</param>
                // <param name="allowCrossPageConnection">Specifies if 
                // the interface can connect to a Web Part
                // on a different page. This is an optional parameter 
                // with a default of false. Note that only some 
                // server side interfaces are allowed to connect across 
                // pages by the Web Part infrastructure. 
                // The IListConsumer interface is not allowed to 
                // connect across pages.</param>
                RegisterInterface("MyListConsumerInterface",                //InterfaceName    
                    InterfaceTypes.IListConsumer,                           //InterfaceType
                    WebPart.LimitOneConnection,                             //MaxConnections
                    ConnectionRunAt.Server,                                 //RunAtOptions
                    this,                                                   //InterfaceObject
                    "",                                                     //InterfaceClientReference
                    "Consume List From",                                    //MenuLabel
                    "Consumes a list from another Web Part.");              //Description
            }
            catch (SecurityException se)
            {
                _registrationErrorOccurred = true;
            }
        }


        // Step #4: Override the CanRunAt method.
        // The CanRunAt method is called by the Web Part infrastructure 
        // during the ASP.NET PreRender event
        // to determine where the Web Part can run based on its current 
        // configuration.

        public override ConnectionRunAt CanRunAt()
        {
            // This Web Part can run on the server.
            return ConnectionRunAt.Server;
        }


        // Step #5: Override the PartCommunicationConnect method.
        // PartCommunicationConnect() is called by the Web Part 
        // infrastructure to notify the Web Part that it
        // is connected during the ASP.NET PreRender event. Relevant 
        // information is passed to the part such as 
        // the interface it is connected over, the Web Part it is being 
        // connected to, and where the part will be running, 
        // either client or server side. 

        // <param name="interfaceName">Friendly name of the interface 
        // that is being connected</param>
        // <param name="connectedPart">Reference to the other Web Part 
        // that is being connected to</param>
        // <param name="connectedInterfaceName">Friendly name of the 
        // interface on the other Web Part</param>
        // <param name="runAt">Where the interface should 
        // execute</param>
        public override void PartCommunicationConnect(string interfaceName,
            WebPart connectedPart,
            string connectedInterfaceName,
            ConnectionRunAt runAt)
        {
            // Keep track of connection state.
            if (interfaceName == "MyListConsumerInterface")
            {
                _connected = true;
                _connectedWebPartTitle = SPEncode.HtmlEncode(connectedPart.Title);
            }
        }


        // Step #6: Implement the ListProviderInit event handler.
        // The connected provider part(s) will call this method during 
        // its PartCommunicationInit phase
        // to pass initialization information to the consumer Web Part.
        // <param name="sender">Reference to the Consumer Web 
        // Part</param>
        // <param name="listProviderInitEventArgs">The args passed by 
        // the provider Web Part</param>
        public void ListProviderInit(object sender, ListProviderInitEventArgs listProviderInitEventArgs)
        {
            // Because this class implements the IListConsumer 
            // interface, it must implement the interface member 
            // ListProviderInit. However, this example
            // doesn't use any initialization data that is passed in 
            // here.
        }


        // Step #7: Implement the ListReady event handler.
        // The connected provider part(s) will call this method during 
        // its PartCommunicationMain phase
        // to pass their primary data to the consumer Web Part.
        // <param name="sender">Reference to the provider Web 
        // Part</param>
        // <param name="listReadyEventArgs">The args passed by the provider Web Part</param>
        DataTable tableIn = new DataTable();

        public void ListReady(object sender, ListReadyEventArgs listReadyEventArgs)
        {
            // Ensure that all of the Web Part's controls are created.
            EnsureChildControls();

            // Store the List that was passed by the provider Web Part. 
            if (listReadyEventArgs.List != null)
            {
                RollUpDataFormWebPart wp = sender as RollUpDataFormWebPart;

                if (wp != null)
                {
                    
                }
                else
                    throw new Exception("Not data from sender");


                tableIn = listReadyEventArgs.List;

                //Bind the data grid
            //    _dataGrid.DataBind();
            }
        }


        // Step #8: Implement the PartialListReady event handler.
        // The connected provider part(s) will call this method during 
        // its PartCommunicationMain phase to pass partial amounts of 
        // their primary data to the consumer Web Part. This is useful 
        // in scenarios involving large datasets that need to be 
        // streamed.

        // <param name="sender">Reference to the provider Web 
        // Part</param>
        // <param name="partialListReadyEventArgs">The args passed by 
        // the provider Web Part</param>
        public void PartialListReady(object sender, PartialListReadyEventArgs partialListReadyEventArgs)
        {
            // Because this class implements the IListConsumer 
            // interface, it must implement the interface member 
            // PartialListReady. However, this example
            // doesn't use any data that may be passed in here.
        }

        #endregion

       

        public void OpenTemplate(string fpath)
        {
           

            try
            {
                string lib = fpath.Trim();

                //    if (!lib.EndsWith("/"))
                //      lib = lib + "/";


                string fname = lib.Substring(lib.LastIndexOf("/") + 1);
                string lib1Mod = lib.Remove(lib.LastIndexOf("/"));
                string list1Name = lib1Mod.Substring(lib1Mod.LastIndexOf("/") + 1);
                int site1Del = lib1Mod.LastIndexOf("/");
                string site1Url = lib1Mod.Substring(0, site1Del);




                using (SPSite site = new SPSite(site1Url))
                {
                    using (SPWeb web = site.OpenWeb())
                    {

                        SPFile file = web.GetFile(fpath);
                        if (file != null)
                        {


                            Stream stream = file.OpenBinaryStream();
                            xdoc = new XmlDocument();
                            xdoc.Load(stream);


                        }
                    }
                }
            }
            catch { }

           

        }

        private XPathNavigator GetNode(string xpath)
        {
            XPathNavigator root = xdoc.CreateNavigator();
            XmlNamespaceManager xnm = new XmlNamespaceManager(root.NameTable);
          
            XPathNavigator nav = root.SelectSingleNode(xpath);
            return nav;
        }

        private XPathNodeIterator GetNodes(string xpath)
        {
            XPathNavigator root = xdoc.CreateNavigator();
            XmlNamespaceManager xnm = new XmlNamespaceManager(root.NameTable);
          
            XPathNodeIterator nav = root.Select(xpath, xnm);
            return nav;
        }
         


        public bool SendRepsonse()
        {
            bool success = false;
            try
            {

                this.Context.Response.ContentType = "Application/x-msexcel";

                this.Context.Response.Clear();

                this.Context.Response.Buffer = true;



                this.Context.Response.AddHeader("Content-Disposition", "attachment;filename=" + DateTime.Now.ToFileTimeUtc() + " .xml");

                xdoc.Save(this.Context.Response.OutputStream);

                this.Context.Response.Flush();

                success = true;
            }
            catch { }
            return success;
            
            //     Respos.nse.AppendHeader("content-length", tw.)
        //    this.Context.Response.OutputStream = tw;





        }

       XmlDocument xdoc = null;

        protected override void RenderWebPart(HtmlTextWriter output)
        {
            // Check for connection interface registration error
            if (_registrationErrorOccurred)
            {
                output.Write(_registrationErrorMsg);
                return;
            }

            // Ensure that all of the Web Part's controls are created.
            EnsureChildControls();

            // Check if connected.
            if (_connected)
            {
                if (tableIn != null && clicked)
                {
                    try
                    {

                        OpenTemplate(templatePath);

                        if (xdoc != null)
                        {

                            XmlNodeList xnl = xdoc.GetElementsByTagName("Row");

                            for (int i = 0; i < xnl.Count; i++)
                            {
                                XmlNode n = xnl[i];

                                if (n.InnerXml.Contains("{{") && n.InnerXml.Contains("}}"))
                                {

                                    XPathNavigator nav = n.CreateNavigator();

                                    foreach (DataRow dr in tableIn.Rows)
                                    {


                                        XmlNode insert = n.Clone();
                                        XPathNavigator navi = insert.CreateNavigator();
                                        XPathNodeIterator xni = navi.SelectDescendants("Data", "urn:schemas-microsoft-com:office:spreadsheet", false);



                                        while (xni.MoveNext())
                                        {

                                            string value = xni.Current.Value;
                                            if (value.Contains("{{") && value.Contains("}}"))
                                            {
                                                string field = value.Substring(value.IndexOf("{{") + 2, value.IndexOf("}}") - value.IndexOf("{{") - 2);

                                                if (tableIn.Columns.Contains(field))
                                                {

                                                    value = value.Replace("{{" + field + "}}", dr[field].ToString());

                                                    xni.Current.SetValue(value);



                                                }

                                            }



                                        }



                                        nav.InsertBefore(navi);

                                    }


                                    nav.DeleteSelf();
                                    break;
                                }


                            }


                            if (SendRepsonse())
                                output.Write("Output successful.  ");
                            else
                                output.Write("Error outputing file.  ");
                            //XmlNode node = xdoc.SelectSingleNode("//Row[contains(Cell/Data/text(), '{{')]");

                            /**
                            = xdoc.CreateNavigator();
                            //nav.Select
                                 XmlNamespaceManager xnm = new XmlNamespaceManager(xdoc.NameTable);
                            xnm.AddNamespace("", "urn:schemas-microsoft-com:office:spreadsheet");
          
    //

                           XPathNavigator nav2 = nav.SelectSingleNode("//Row", xnm);
                       **/
                            // Line break.





                        }
                        else
                        {
                            if (templatePath == defaulttp)
                                output.Write("Please specify a template location in the web part's properties.");
                            else
                                output.Write("Error retrieving template.  Specified location: " + templatePath);


                            return;

                        }
                        clicked = false;

                    }
                    catch (Exception ex)
                    {
                        output.Write(ex.Message);
                    }

                }

                // Render connected Web Part title.
                output.Write(_connectedWebPartLabel + ": ");
                output.RenderBeginTag(HtmlTextWriterTag.I);
                output.Write(_connectedWebPartTitle);
                output.RenderEndTag();
                output.Write("<br>");
                startBtn.RenderControl(output);

            }
            else
            {
                // The Web Part isn't connected.
                output.Write(_notConnectedMsg);
            }
        }

        Button startBtn;
        // Create Web Part user interface controls.
        protected override void CreateChildControls()
        {
            startBtn = new Button();

            startBtn.Text = "Export Report";
            startBtn.Click += new EventHandler(startBtn_Click);

            this.Controls.Add(startBtn);

  }
        bool clicked = false;
        void startBtn_Click(object sender, EventArgs e)
        {
            clicked = true;
        }

    }
}
